﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for UserAdapter
/// </summary>
public class UserAdapter
{
	public UserAdapter()
	{
		//
		// TODO: Add constructor logic here
		//
	}
    /// <summary>
    /// login from web app
    /// </summary>
    /// <param name="username"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    public UserEntity LoginWebApp(string username, string password)
    {
        BookContextDataContext bContext = new BookContextDataContext();
        try
        {
            if (username != null && password != null)
            {
                AuthenAdapter authen = new AuthenAdapter();
                password = authen.Encrypt(password, true);
                User user = bContext.Users.SingleOrDefault
                     (t => t.Account == username && t.Password == password);
                if (user != null)
                {
                    UserEntity userEntity = new UserEntity(user);
                    userEntity.isLogin = true;
                    bContext.SubmitChanges();
                    return userEntity;
                }
            }
        }
        catch { }
        return null;
    }

    private int CalculateOrderNumberDevice(string UserAccount)
    {
        int _Order = 0;
        BookContextDataContext context = new BookContextDataContext();
        List<Device> listDevice = new List<Device>();
        listDevice = context.Devices.Where(t => t.UserAccount == UserAccount).ToList();

        if (listDevice.Count > 0)
        {
            // Device for regist is available
            for (int i = 1; i <= listDevice.Count; i++)
            {
                if (listDevice.Exists(t => t.DeviceName == UserAccount + i.ToString()) == false)
                {
                    _Order = i;
                    break;
                }

            }

        }
        return _Order;

    }



    public UserLogin LoginFromDevice(String username, String password, String deviceID)
    {
        UserLogin result = new UserLogin();
        result.DevideName = "";
        result.UserToken = "";
        BookContextDataContext bContext = new BookContextDataContext();

        if (username != null && password != null)
        {

            // Case 1: Device's already login, Login failure
            Device deviceCheck1 = bContext.Devices.Where(t => t.UserAccount == username && t.DeviceID == deviceID && t.IsLogin == true).SingleOrDefault();
            if (deviceCheck1 != null)
            {
                result.Message = Utils.Message1;
                return result;
            }
            AuthenAdapter authen = new AuthenAdapter();
            password = authen.Encrypt(password, true);
            User user = bContext.Users.SingleOrDefault(t => t.Account == username && t.Password == password && t.Active == true);

            if (user != null)
            {

                    List<Device> lstDevice = (from d in bContext.Devices
                                              where d.UserAccount == username
                                              select d).ToList();
                    // Case 2: This Account is login in other devices               
                    Device deviceCheck2 = bContext.Devices.Where(t => t.UserAccount == username && t.IsLogin == true).SingleOrDefault();
                    //Other device is login
                    if (deviceCheck2 != null)
                    {

                        Device deviceCheck3 = bContext.Devices.Where(t => t.UserAccount == username && t.DeviceID == deviceID && t.IsLogin == false).SingleOrDefault();
                        // Case 2.1: Device was exist
                        if (deviceCheck3 != null)
                        {

                            deviceCheck3.IsLogin = true;
                            deviceCheck2.IsLogin = false;
                            bContext.SubmitChanges();

                            result.Message = Utils.Message2;
                            result.DevideName = deviceCheck3.DeviceName;
                            result.UserToken = user.Token;
                            return result;
                        }
                        // Case 2.2: Add new device
                        else
                        {
                            if (lstDevice.Count() == 0)
                            {
                                Device device = new Device();
                                device.DeviceID = deviceID;
                                device.UserAccount = username;
                                device.IsLogin = true;
                                deviceCheck2.IsLogin = false;
                                int orderDevice = CalculateOrderNumberDevice(username);
                                device.DeviceName = username + orderDevice.ToString();

                                bContext.Devices.InsertOnSubmit(device);
                                bContext.SubmitChanges();

                                result.DevideName = username + orderDevice.ToString();
                                result.UserToken = user.Token;
                                result.Message = Utils.Message2;


                            }
                            else
                            {
                                result.Message = Utils.Message4;
                            }
                        }

                    }

                    else
                    {
                        // Check device exist or not
                        Device deviceCheck = bContext.Devices.Where(t => t.UserAccount == username && t.DeviceID == deviceID && t.IsLogin == false).SingleOrDefault();

                        if (deviceCheck != null)
                        {
                            deviceCheck.IsLogin = true;
                            bContext.SubmitChanges();

                            result.Message = Utils.Message3;
                            result.DevideName = deviceCheck.DeviceName;
                            result.UserToken = user.Token;
                            return result;
                        }
                        else
                        {
                                Device device = new Device();
                                device.DeviceID = deviceID;
                                device.UserAccount = username;
                                device.IsLogin = true;


                                int orderDevice = CalculateOrderNumberDevice(username);
                                device.DeviceName = username + orderDevice.ToString();

                                bContext.Devices.InsertOnSubmit(device);
                                bContext.SubmitChanges();

                                result.DevideName = username + orderDevice.ToString();
                                result.UserToken = user.Token;
                                result.Message = Utils.Message3;
                           
                        }
                    }

                }

        }

        return result;
        

    }

    /// <summary>
    /// get list user
    /// </summary>    
    /// <returns></returns>
    public List<UserEntity> getAllUser()
    {
        List<UserEntity> users = new List<UserEntity>();
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            List<User> list = context.Users.Where(u => u.RoleID == 2).ToList();
            foreach (User user in list)
            {
                users.Add(new UserEntity(user));
            }
            return users;
        }
        catch { return null; }
    }


    public bool CheckOldPassword(string username, string pass)
    {
        BookContextDataContext context = new BookContextDataContext();
        AuthenAdapter auAdap = new AuthenAdapter();
        try
        {
            string enpass = auAdap.Encrypt(pass, true);
            User user = context.Users.SingleOrDefault(t => t.Account== username && t.Password == enpass);
            if (user != null)
                return true;
            else return false;
        }
        catch { return false; }
    }
    /// <summary>
    /// Update Account 
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    public bool UpdateUser(UserEntity user)
    {
        BookContextDataContext context = new BookContextDataContext();
        AuthenAdapter authen = new AuthenAdapter();
        try
        {
            User user1 = context.Users.SingleOrDefault(t => t.Account == user.Account);

            if (user1 != null)
            {
                if (user.Password != null)
                {
                    user1.Password = user.Password;
                    user1.Token = user.Token;
                }
                user1.RoleID = user.RoleID;
                user1.Mail = user.Mail;
                user1.Active = user.Active;

                context.SubmitChanges();
                return true;

            }
            else
                return false;
        }
        catch { return false; }
    }
    /// <summary>
    /// Create Account
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>

    public bool CreateUser(UserEntity user)
    {
        BookContextDataContext context = new BookContextDataContext();
        AuthenAdapter authen = new AuthenAdapter();
        try
        {
            User user1 = context.Users.SingleOrDefault(t => t.Account == user.Account);

            if (user1 == null)//Checking exist or not.
            {
                user1 = new User();
                user1.Account = user.Account;
                user1.Password = user.Password;
                user1.Token = user.Token;
                user1.DateCreate = user.DateCreate;
                user1.RoleID = user.RoleID;
                user1.Mail = user.Mail;
                user1.Active = user.Active;
                context.Users.InsertOnSubmit(user1);
                context.SubmitChanges();

                return true;
            }
        }
        catch { }
        return false;
    }

    /// <summary>
    /// Check Exist Account by username
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    public bool IsUserExist(string username)
    {
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            User user1 = context.Users.SingleOrDefault(t => t.Account == username);
            if (user1 != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch { return false; }

    }
    /// <summary>
    /// Check Exist Account by token
    /// </summary>
    /// <param name="session"></param>
    /// <returns></returns>
    public bool IsTokenExist(string session)
    {
        var context = new BookContextDataContext();
        try
        {
            User user1 = context.Users.SingleOrDefault(t => t.Token == session);
            if (user1 != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch { return false; }

    }
    /// <summary>
    /// Get Account entity by unserName
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    public UserEntity getUserbyName(string userName)
    {

        BookContextDataContext context = new BookContextDataContext();
        try
        {
            User user = context.Users.SingleOrDefault(u => u.Account == userName);

            if (user != null)
            {
                return new UserEntity(user);
            }
        }
        catch { }
        return null;
    }

    /// <summary>
    /// Delete Account  by unserName
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    public bool DeleteUser(string username)
    {

        List<BookEntity> categories = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();

        try
        {
            List<Book> list = bookContext.Books.Where(b => b.Author == username).ToList();
            if (list.Count == 0)
            {
                User user = bookContext.Users.SingleOrDefault(u => u.Account == username);
                bookContext.Users.DeleteOnSubmit(user);
                bookContext.SubmitChanges();
            }
            else
            {
                foreach (Book book in list)
                {
                    // Delete bookDetail by bookID
                    List<BookDetail> listBookDetail = bookContext.BookDetails.Where(b => b.BookID == book.ID).ToList();
                    bookContext.BookDetails.DeleteAllOnSubmit(listBookDetail);

                }
                // Delete Book by author
                bookContext.Books.DeleteAllOnSubmit(list);

                User user = bookContext.Users.SingleOrDefault(u => u.Account == username);
                bookContext.Users.DeleteOnSubmit(user);
                bookContext.SubmitChanges();

            }

            return true;
        }
        catch
        {
            return false;
        }
    }
}